import Vue from 'vue';
import { WxGloablMessageType, WXSOCKET_TYPES_REQUEST, WXSOCKET_TYPES_RESPONSE } from '@/constants/global';
import { getEnterPriseCarList } from '@/api/moniter';
// import folderIcon from '@/assets/icons/folder-yellow.svg?inline'
import {
  ACCESS_TOKEN,
  ADD_ALERTTOTAL,
  ADD_LOCALMESSAGE,
  GPSLIST,
  PUSH_HISTORYVIDEOLIST,
  PUSH_MESSAGE,
  PUSH_VIDEOLIST,
  QUEUELIST,
  SET_ALERTSTATE_ALERTCOUNT,
  SET_ALERTTOTAL,
  SET_CARSTATE_CARTOTAL,
  SET_CARSTATE_OFFLINECOUNT,
  SET_CARSTATE_ONLINECOUNT,
  SET_ISALLCARSUBSCRIPTIONED,
  WEBSOCKET,
  CURRENT_USER,
  IS_LOCKSCREEN,
} from '@/store/mutation-types';
import { defineStore } from 'pinia';
import { createStorage } from '@/utils/Storage';
import { store } from '@/store';
import { ResultEnum } from '@/enums/httpEnum';

const Storage = createStorage({ storage: localStorage });
import { getUserInfo, login } from '@/api/system/user';
import { storage } from '@/utils/Storage';
import { resolve } from 'path/posix';
import { reject } from 'lodash';

export interface wxWebsocketState {
  isAllCarSubScriptioned: Boolean;
  subScriptionDict: Object;
  carOfItemDict: Object;
  carState: {
    onlineCarCount: Number; // 在线车辆
    offlineCarCount: Number; // 离线车辆
    redcodeCarCount: Number; // 红码车辆
    unregisterCarCount: Number; // 未登记车辆
    carTotalCount: Number; // 车辆总数
  };
  alertState: {
    alertCount: Number; // 报警总数
  };
  alertTotal: Number;
  serialNumber: Number;
  websocket?: WebSocket;
  wsQueue: Object;
  interval?: Interval;
  // websocketFlag: 0, // 正在发送
  messageList: Array<any>;
  needReSendMessageList: Array<any>; // 发送失败后需要重发的消息
  needReConnectSendMessageList: Array<any>; // 重连之后需要重新发送的消息
  // 各种List
  // 鉴权：type 1001
  list1001: Array<any>;
  // 视频列表
  videoList: Object;
  // 历史视频列表
  historyVideoList: Array<any>;
  // 本地消息字典列表，包含消息和回调
  localMessageList: Object;
}

export const wxWebsocketStore = defineStore({
  id: 'wx-websocket',
  state: (): wxWebsocketState => ({
    isAllCarSubScriptioned: false, // 全部车辆消息是否订阅完成
    subScriptionDict: {},
    carOfItemDict: {},
    carState: {
      onlineCarCount: 0, // 在线车辆
      offlineCarCount: 0, // 离线车辆
      redcodeCarCount: 0, // 红码车辆
      unregisterCarCount: 0, // 未登记车辆
      carTotalCount: 0, // 车辆总数
    },
    alertState: {
      alertCount: 0, // 报警总数
    },
    alertTotal: 0,
    serialNumber: 0,
    websocket: undefined,
    wsQueue: {},
    interval: undefined,
    // websocketFlag: 0, // 正在发送
    messageList: [],
    needReSendMessageList: [], // 发送失败后需要重发的消息
    needReConnectSendMessageList: [], // 重连之后需要重新发送的消息
    // 各种List
    // 鉴权：type 1001
    list1001: [],
    // 视频列表
    videoList: {},
    // 历史视频列表
    historyVideoList: [],
    // 本地消息字典列表，包含消息和回调
    localMessageList: {},
  }),
  getters: {
    getIsAllCarSubScriptioned(state) {
      return this.isAllCarSubScriptioned;
    },
    getAlertState(state) {
      return this.alertState;
    },
    getWebsocket(state) {
      return this.websocket;
    },
    getQueueList(state) {
      return this.wsQueue;
    },
    getList1001(state) {
      return this.list1001;
    },
    getVideoList(state) {
      return this.videoList;
    },
    getLocalMessageList(state) {
      return this.localMessageList;
    },
    getCarState(state) {
      return this.carState;
    },
  },
  actions: {
    setIsAllCarSubScriptioned(isAllCarSubScriptioned: Boolean) {
      this.isAllCarSubScriptioned = isAllCarSubScriptioned;
    },
    // getCarList(queryParams) {
    //   return new Promise((resolve, reject) => {
    //   });
    // },
    setWebsocket({ context, uri, onClose }) {
      if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
        // 已经连接的话直接返回
        console.log('已经连接过');
        return Promise.resolve(1);
      }
      const ws = new WebSocket(uri);
      this.websocket = ws;
      return new Promise((resolve, reject) => {
        ws.onopen = () => {
          console.log('WebSocket 打开链接成功');
          resolve(1);
        };
        ws.onclose = () => {
          // 没有token的时候不要去重连，登录的时候会清除掉token
          if (storage.get(ACCESS_TOKEN)) {
            // onClose是重连的回调方法，这里会回调到调用setWebsocket的地方
            onClose();
          }
          console.log('websocket 链接已关闭');
        };
        ws.onmessage = (e) => {
          this.carthis.carTotalCount++;
          // const message = JSONbig.parse(e.data) // 以前需要转换一下long类型，现在后端改成字符串返回之后就不需要转换了
          const message = e.data;
          const messageReplaySerialNumber = message.serialNumber; // 拿到返回来的序列号，方便调用不同的回调方法
          const localMessageItem = this.localMessageList[messageReplaySerialNumber];
          // if (localMessageItem.onMessage) {
          if (localMessageItem && localMessageItem.hasOwnProperty('onMessage')) {
            // 如果需要回调的就在这里回调回去
            localMessageItem.onMessage(message);
          }
          if (message && message.data && message.data.result && message.data.result !== 0) {
            // result不为0的时候就是出错
            // context.$message.error(message.data.data);
          }
          // auth type: 1001
          if (message && message.type === 1001) {
            // 在这里要判断一下index如果是2的话就是token过期了，这里直接清除掉token然后跳转或者刷新页面到login
            if (message.data && message.data.index === 2) {
              // 2是token过期
              storage.remove(ACCESS_TOKEN);
              window.location.reload();
              return;
            }
            if (message.data && message.data.index === 0) {
              // 0是鉴权失败
              storage.remove(ACCESS_TOKEN);
              window.location.reload();
              return;
            }
            this.list1001.push(message)
          }
          // if (message && message.type === 1003) {
          //   // 车辆实时位置信息
          //   commit(GPSLIST, message);
          // }
          if (this.subScriptionDict.hasOwnProperty(message.type)) {
            // 这里订阅统一回调
            const subScriptions = this.subScriptionDict[message.type]
            for (let subscriptionIndex = 0; subscriptionIndex < subScriptions.length; subscriptionIndex++) {
              // item: { tag: x, callback: function }
              const subScriptionItem = subScriptions[subscriptionIndex];
              // 这里不需要管tag，直接callback回去
              subScriptionItem.callback(message);
            }
          }
          if (message && message.type === WXSOCKET_TYPES_RESPONSE.DEVICE_ONOFF) {
            if (message.data) {
              const onoffData = message.data;
              const carItem = this.carOfItemDict[onoffData.carId];
              const carItems = Object.values(this.carOfItemDict);
              carItem.online = onoffData.online;
              let onlineCarCount = 0;
              let offlineCarCount = 0;
              for (let carItemIndex = 0; carItemIndex < carItems.length; carItemIndex++) {
                const _carItem = carItems[carItemIndex];
                if (_carItem.online) {
                  onlineCarCount++;
                } else {
                  offlineCarCount++;
                }
              }
              this.carthis.onlineCarCount = carOnlineCount;
              this.carthis.offlineCarCount = offlineCarCount;
            }
          }
          if (message && message.type === WXSOCKET_TYPES_RESPONSE.DEVICE_ALERT_RESPONE) {
            this.alertthis.alertCount++;
          }
          if (message && message.type === WXSOCKET_TYPES_RESPONSE.SELECT_VIDEOS_RESPONSE) {
            this.videoList[message.serialNumber, message.data]
          }
          if (message && message.type === WXSOCKET_TYPES_REQUEST.HISTORY_VIDEOS_LIST) {
            this.historyVideoList = message;
          }
        }
      });
    },
  //   getCarList(queryParams) {
  //     return new Promise((resolve, reject) => {
  //       console.log(queryParams);
  //       getEnterPriseCarList(queryParams)
  //         .then((res) => {
  //           const rtDict = {
  //             totalCarCount: 0,
  //             carOfItemDict: {},
  //             carTreeData: [],
  //           };
  //           let onlineCarCount = 0;
  //           let offlineCarCount = 0;
  //           if (!res.data) return;
  //           for (let departmentIndex = 0; departmentIndex < res.data.length; departmentIndex++) {
  //             // 部门
  //             const department = res.data[departmentIndex];
  //             department.title = department.departmentName;
  //             department.key = department.departmentId.toString();
  //             department.children = [];
  //             department.type = 'folder';
  //             for (
  //               let motorcadeIndex = 0;
  //               motorcadeIndex < department.carInfoStatusOfDepartment.length;
  //               motorcadeIndex++
  //             ) {
  //               // 车队
  //               const motorcade = department.carInfoStatusOfDepartment[motorcadeIndex]
  //               motorcade.title = motorcade.motorcadeName
  //               motorcade.key = motorcade.motorcadeId.toString()
  //               motorcade.scopedSlots = { title: 'custom' }
  //               motorcade.children = []
  //               motorcade.type = 'folder'
  //               for (let carIndex = 0; carIndex < motorcade.carInfoStatusOfMotorcade.length; carIndex++) {
  //                 rtDict['totalCarCount']++
  //                 const carItem = motorcade.carInfoStatusOfMotorcade[carIndex]
  //                 const listCarItem = JSON.parse(JSON.stringify(carItem))
  //                 listCarItem.title = listCarItem.licenseNumber
  //                 listCarItem.key = listCarItem.carId.toString()
  //                 // listCarItem.icon = <img src={folderIcon} />
  //                 listCarItem.scopedSlots = { title: 'custom' }
  //                 listCarItem.type = 'car'
  //                 listCarItem.online = listCarItem.isOnlineSum > 0
  //                 listCarItem['frontDeep'] = `${departmentIndex}-${motorcadeIndex}-${carIndex}` // 前端用来做深度的字段
  //                 if (listCarItem.online) {
  //                   onlineCarCount++
  //                 } else {
  //                   offlineCarCount++
  //                 }
  //                 rtDict.carOfItemDict[listCarItem.key] = listCarItem
  //                 this.carOfItemDict[listCarItem.key] = listCarItem
  //                 // this.$set(this.carOfItemDict, listCarItem.key, listCarItem)
  //                 motorcade.children.push(listCarItem)
  //               }
  //               department.children.push(motorcade)
  //             }
  //             rtDict.carTreeData.push({
  //               type: 'folder',
  //               title: department.departmentName,
  //               key: department.departmentId.toString(),
  //               scopedSlots: { title: 'custom' },
  //               children: department.children,
  //             });
  //           }
  //           // commit(SET_CARSTATE_ONLINECOUNT, onlineCarCount);
  //           // commit(SET_CARSTATE_OFFLINECOUNT, offlineCarCount);
  //           resolve({ rtDict, res });
  //         }).catch(e => {
  //           reject(e);
  //         });
  //     });
  //   },
  //   subScriptionMessage({ type, tag, callback }) {
  //     if (this.subScriptionDict[type] && this.subScriptionDict[type].length >= 0) {
  //       // 可以根据type && tag来做下去重防止重复订阅
  //       this.subScriptionDict[type].push({
  //         tag,
  //         callback,
  //       })
  //       return;
  //     }
  //     this.subScriptionDict[type] = []
  //     this.subScriptionDict[type].push({
  //       tag,
  //       callback,
  //     });
  //   },
  //   setOnlineCarCount(onlineCarCount) {
  //     // commit(SET_CARSTATE_ONLINECOUNT, onlineCarCount);
  //   },
  //   setOfflineCarCount(offlineCarCount) {
  //     // commit(SET_CARSTATE_OFFLINECOUNT, offlineCarCount);
  //   },
  //   closeWebsocket(callback) {
  //     this.websocket!!.close();
  //     callback();
  //   },
  //   shiftList001() {
  //     this.list1001.shift();
  //   },
  //   sendReMessage() {
  //     // 这里开始重发之前发送失败的消息
  //     if (this.needReSendMessageList.length > 0) {
  //       for (let reSendIndex = 0; reSendIndex < this.needReSendMessageList.length; reSendIndex++) {
  //         const reSendMessageObj = this.needReSendMessageList[reSendIndex];
  //         this.sendMessage(reSendMessageObj)
  //       }
  //     }
  //   },
  //   setWebsocket({ context, uri, onClose }) {
  //     if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
  //       // 已经连接的话直接返回
  //       console.log('已经连接过');
  //       return Promise.resolve(1);
  //     }
  //     const ws = new WebSocket(uri);
  //     this.websocket = ws;
  //     return new Promise((resolve, reject) => {
  //       ws.onopen = () => {
  //         // commit(PUSH_MESSAGE, {
  //         //   message: '推送服务连接成功',
  //         //   type: WxGloablMessageType.WebsocketOpened,
  //         //   messageType: 'message',
  //         // });
  //         console.log('WebSocket 打开链接成功');
  //         // ws.send(JSON.stringify(obj))
  //         resolve(1);
  //       };
  //       ws.onclose = () => {
  //         // 没有token的时候不要去重连，登录的时候会清除掉token
  //         if (storage.get(ACCESS_TOKEN)) {
  //           // onClose是重连的回调方法，这里会回调到调用setWebsocket的地方
  //           onClose();
  //         }
  //         console.log('websocket 链接已关闭');
  //       };
  //       ws.onmessage = e => {
  //         this.carthis.carTotalCount++;
  //         // const message = JSONbig.parse(e.data) // 以前需要转换一下long类型，现在后端改成字符串返回之后就不需要转换了
  //         const message = e.data;
  //         const messageReplaySerialNumber = message.serialNumber; // 拿到返回来的序列号，方便调用不同的回调方法
  //         const localMessageItem = this.localMessageList[messageReplaySerialNumber];
  //         // if (localMessageItem.onMessage) {
  //         if (localMessageItem && localMessageItem.hasOwnProperty('onMessage')) {
  //           // 如果需要回调的就在这里回调回去
  //           localMessageItem.onMessage(message);
  //         }
  //         if (message && message.data && message.data.result && message.data.result !== 0) {
  //           // result不为0的时候就是出错
  //           // context.$message.error(message.data.data);
  //         }
  //         // auth type: 1001
  //         if (message && message.type === 1001) {
  //           // 在这里要判断一下index如果是2的话就是token过期了，这里直接清除掉token然后跳转或者刷新页面到login
  //           if (message.data && message.data.index === 2) {
  //             // 2是token过期
  //             storage.remove(ACCESS_TOKEN);
  //             window.location.reload();
  //             return;
  //           }
  //           if (message.data && message.data.index === 0) {
  //             // 0是鉴权失败
  //             storage.remove(ACCESS_TOKEN);
  //             window.location.reload();
  //             return;
  //           }
  //           this.list1001.push(message)
  //         }
  //         // if (message && message.type === 1003) {
  //         //   // 车辆实时位置信息
  //         //   commit(GPSLIST, message);
  //         // }
  //         if (this.subScriptionDict.hasOwnProperty(message.type)) {
  //           // 这里订阅统一回调
  //           const subScriptions = this.subScriptionDict[message.type]
  //           for (let subscriptionIndex = 0; subscriptionIndex < subScriptions.length; subscriptionIndex++) {
  //             // item: { tag: x, callback: function }
  //             const subScriptionItem = subScriptions[subscriptionIndex];
  //             // 这里不需要管tag，直接callback回去
  //             subScriptionItem.callback(message);
  //           }
  //         }
  //         if (message && message.type === WXSOCKET_TYPES_RESPONSE.DEVICE_ONOFF) {
  //           if (message.data) {
  //             const onoffData = message.data;
  //             const carItem = this.carOfItemDict[onoffData.carId];
  //             const carItems = Object.values(this.carOfItemDict);
  //             carItem.online = onoffData.online;
  //             let onlineCarCount = 0;
  //             let offlineCarCount = 0;
  //             for (let carItemIndex = 0; carItemIndex < carItems.length; carItemIndex++) {
  //               const _carItem = carItems[carItemIndex];
  //               if (_carItem.online) {
  //                 onlineCarCount++;
  //               } else {
  //                 offlineCarCount++;
  //               }
  //             }
  //             this.carthis.onlineCarCount = carOnlineCount;
  //             this.carthis.offlineCarCount = offlineCarCount;
  //           }
  //         }
  //         if (message && message.type === WXSOCKET_TYPES_RESPONSE.DEVICE_ALERT_RESPONE) {
  //           this.alertthis.alertCount++;
  //         }
  //         if (message && message.type === WXSOCKET_TYPES_RESPONSE.SELECT_VIDEOS_RESPONSE) {
  //           // Vue.set(this.videoList, videoItem.serialNumber, videoItem.data);
  //           this.videoList[message.serialNumber, message.data]
  //           // commit(PUSH_VIDEOLIST, message);
  //         }
  //         if (message && message.type === WXSOCKET_TYPES_REQUEST.HISTORY_VIDEOS_LIST) {
  //           this.historyVideoList = message;
  //           // commit(PUSH_HISTORYVIDEOLIST, message);
  //         }
  //       };
  //     });
  //   },
    sendMessage(payload) {
      this.messageList.push(payload);
      console.log(this.messageList)
      if (this.interval === null) {
        // 创建interval 每隔100毫秒从list中取出来发送到websocket服务器
        this.interval = setInterval(() => {
          // 可以使用flag保证不重复发送，只有这次发送完毕之后才去发送下一条，这里先删除不使用
          if (this.messageList && this.messageList.length > 0) {
            // list里面有消息才发送 使用 shift 发完之后删掉
            const messageObj = this.messageList.shift();
            // 发送的时候把 serialNumber + 1 然后赋值给 message
            this.serialNumber += 1;
            if (messageObj.hasOwnProperty('serialNumber')) {
              // 实时视频代码部分需要用到，保留
              messageObj.serialNumber = this.serialNumber;
            }
            messageObj.message['serialNumber'] = this.serialNumber;
            try {
              this.websocket.send(JSON.stringify(messageObj.message));
            } catch (e) {
              this.needReSendMessageList.push(messageObj);
              // 发送失败，一般是websocket未连接成功造成的，这里可以直接重发或者加入到重发的队列中
              console.log('发送失败');
            }
            this.localMessageList[messageObj.message.serialNumber] = messageObj // 发送完毕后添加到本地保存起来
            // commit(ADD_LOCALMESSAGE, messageObj);
            messageObj.callback(messageObj);
            // 一条消息发送完毕
          }
        }, 100);
      }
    },
  //   addLocalMessage(messageItem) {
  //     // commit(ADD_LOCALMESSAGE, messageItem);
  //   },
  //   setLocalMessageList(queueItem) {
  //     // commit(QUEUELIST, queueItem);
  //   },
  },
});

// Need to be used outside the setup
export function useWxwebsocketStoreWidthOut() {
  let _store: any = null;
  try {
    _store = wxWebsocketStore(store);
  } catch (e) {
    console.error(e);
  }
  return _store;
}
